{
  "nbformat": 4,
  "nbformat_minor": 2,
  "metadata": {},
  "cells": [
    {
      "metadata": {},
      "source": [
        "<td>\n",
        "   <a target=\"_blank\" href=\"https://labelbox.com\" ><img src=\"https://labelbox.com/blog/content/images/2021/02/logo-v4.svg\" width=256/></a>\n",
        "</td>"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "<td>\n",
        "<a href=\"https://colab.research.google.com/github/Labelbox/labelbox-python/blob/master/examples/model_experiments/model_slices.ipynb\" target=\"_blank\"><img\n",
        "src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
        "</td>\n",
        "\n",
        "<td>\n",
        "<a href=\"https://github.com/Labelbox/labelbox-python/tree/master/examples/model_experiments/model_slices.ipynb\" target=\"_blank\"><img\n",
        "src=\"https://img.shields.io/badge/GitHub-100000?logo=github&logoColor=white\" alt=\"GitHub\"></a>\n",
        "</td>"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# Model Slices\n",
        "\n",
        "Model Slice functions similarly to Catalog Slice, with both essentially being saved searches. However, there are key differences in their functionalities. While Catalog Slice searches within a specific data catalog, Model Slice extends its data row search across a model run in a model. You can construct a Model Slice by using one or more filters to curate a collection of data rows. Often users will combine filters to surface high-impact data and then save the results as a Model Slice.\n",
        "\n",
        "This notebook is used to go over some common Labelbox SDK methods to interact with Model Slices created through the Labelbox platform.\n",
        "\n",
        "See [Slices](https://docs.labelbox.com/docs/slices-1) for more information on modifying Model Slices."
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "!pip install labelbox"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "import labelbox as lb\n",
        "import uuid"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "## API Key and Client\n",
        "See the developer guide for [creating an API key](https://docs.labelbox.com/reference/create-api-key)."
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# Add your API key\n",
        "API_KEY = \"\"\n",
        "# To get your API key go to: Workspace settings -> API -> Create API Key\n",
        "client = lb.Client(api_key=API_KEY)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "## Create Model Slice\n",
        "\n",
        "In order to interact with model slices, you must create a Model Experiment with a Model Run and then create a Model Slice through the platform. The steps below go over this process. See [Model](https://docs.labelbox.com/reference/model) from our developer guides for more information."
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "### Creating Model Experiment\n",
        "\n",
        "To create a Model Experiment you will need to create an ontology. See [Ontology](https://docs.labelbox.com/reference/ontology) for more information"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "#### Ontology"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "classification_features = [\n",
        "    lb.Classification(\n",
        "        class_type=lb.Classification.Type.CHECKLIST,\n",
        "        name=\"Quality Issues\",\n",
        "        options=[\n",
        "            lb.Option(value=\"blurry\", label=\"Blurry\"),\n",
        "            lb.Option(value=\"distorted\", label=\"Distorted\")\n",
        "        ]\n",
        "    )\n",
        "\n",
        "]\n",
        "\n",
        "ontology_builder = lb.OntologyBuilder(\n",
        "    tools=[],\n",
        "    classifications=classification_features\n",
        ")\n",
        "\n",
        "ontology = client.create_ontology(\n",
        "  \"Ontology from new features\",\n",
        "  ontology_builder.asdict(),\n",
        "  media_type=lb.MediaType.Image\n",
        ")"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "#### Model Experiment"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "model = client.create_model(\n",
        "  name=\"Model Slice Demo\",\n",
        "  ontology_id=ontology.uid\n",
        ")"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "### Creating a Model Run from Model Experiment\n",
        "\n",
        "On this step we will need to create a dataset to attach data rows to our model run. See [Dataset](https://docs.labelbox.com/reference/dataset) for more information."
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "#### Dataset and Data Rows"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# send a sample image as data row for a dataset\n",
        "global_key = str(uuid.uuid4())\n",
        "\n",
        "test_img_url = {\n",
        "    \"row_data\":\n",
        "        \"https://storage.googleapis.com/labelbox-datasets/image_sample_data/2560px-Kitano_Street_Kobe01s5s4110.jpeg\",\n",
        "    \"global_key\":\n",
        "        global_key\n",
        "}\n",
        "\n",
        "dataset = client.create_dataset(name=\"foundry-demo-dataset\")\n",
        "task = dataset.create_data_rows([test_img_url])\n",
        "task.wait_till_done()\n",
        "\n",
        "print(f\"Errors: {task.errors}\")\n",
        "print(f\"Failed data rows: {task.failed_data_rows}\")"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "#### Model Run and Attach Data Rows"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "model_run_name = \"Model Slice Demo\"\n",
        "example_config = {\n",
        "    \"learning_rate\": 0.001, \n",
        "    \"batch_size\": 32, \n",
        "}\n",
        "model_run = model.create_model_run(name=model_run_name, config=example_config)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "model_run.upsert_data_rows(global_keys=[global_key])"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "### Make Model Slice Inside UI\n",
        "\n",
        "Creating a Model Slice is currently not supported through the SDK, however, to showcase how to interact with Model Slice, we are going to generate a Model Slice through the UI.\n",
        "\n",
        "#### Workflow\n",
        "\n",
        "1. Navigate to ***Model*** section of the Labelbox Platform, select the ***Experiment*** type, and select the Model Experiment that was created.\n",
        "2. You must have a filter created in order to save a slice. For this example, click ***Search your data*** dropdown and then ***Data row***.\n",
        "3. Change ***is one of*** dropdown to ***is not one of*** then type \"test\" into the ***Search for an id*** search box.\n",
        "4. Hit ***Enter*** and select ***Save slice***.\n",
        "5. Give the slice a name and select ***Save***.\n",
        "6. Above the ***Search your data*** dropdown you will see your slice's name. Select that dropdown and click ***Copy slice ID***.\n",
        "7. Paste the ***Slice ID*** below."
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "SLICE_ID = \"\""
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "### Get Model Slice"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "model_slice = client.get_model_slice(SLICE_ID)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "### Obtain Data Row IDs from Model Slice"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "data_row_ids = model_slice.get_data_row_ids(model_run.uid)\n",
        "\n",
        "for data_row_id in data_row_ids:\n",
        "    print(data_row_id)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "### Obtain Data Row Identifiers Objects"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "data_rows = model_slice.get_data_row_identifiers(model_run.uid)\n",
        "\n",
        "for data_row in data_rows:\n",
        "    print(data_row)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "### Model Slice Attributes"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# name (str)\n",
        "model_slice.name\n",
        "\n",
        "# description (str)\n",
        "model_slice.description\n",
        "\n",
        "# updated at (datetime)\n",
        "model_slice.updated_at\n",
        "\n",
        "# created at (datetime)\n",
        "model_slice.created_at\n",
        "\n",
        "# filter (list[dict])\n",
        "model_slice.filter"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    }
  ]
}